package com.atxwq.shop.order.service.impl;

import com.atxwq.shop.common.exception.GlobalException;
import com.atxwq.shop.feign.cart.CartFeignClient;
import com.atxwq.shop.feign.product.ProductFeignClient;
import com.atxwq.shop.feign.user.UserFeignClient;
import com.atxwq.shop.model.dto.h5.OrderInfoDto;
import com.atxwq.shop.model.entity.h5.CartInfo;
import com.atxwq.shop.model.entity.order.OrderInfo;
import com.atxwq.shop.model.entity.order.OrderItem;
import com.atxwq.shop.model.entity.order.OrderLog;
import com.atxwq.shop.model.entity.product.ProductSku;
import com.atxwq.shop.model.entity.user.UserAddress;
import com.atxwq.shop.model.entity.user.UserInfo;
import com.atxwq.shop.model.vo.common.ResultCodeEnum;
import com.atxwq.shop.model.vo.h5.TradeVo;
import com.atxwq.shop.order.mapper.OrderInfoMapper;
import com.atxwq.shop.order.mapper.OrderItemMapper;
import com.atxwq.shop.order.mapper.OrderLogMapper;
import com.atxwq.shop.order.service.OrderInfoService;
import com.atxwq.utils.AuthContextUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description TODO
 * @Date 2025/5/23 11:07
 * @Created by 12336
 */

@Service
public class OrderInfoServiceImpl implements OrderInfoService {

    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderLogMapper orderLogMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;



    @Override
    public TradeVo getTrade() {

        List<CartInfo> cartInfoList = cartFeignClient.getAllCkecked();
        //创建list集合用于封装订单项
        List<OrderItem> orderItemList = new ArrayList<>();
        for (CartInfo cartInfo : cartInfoList) {
            OrderItem orderItem = new OrderItem();
            orderItem.setSkuId(cartInfo.getSkuId());
            orderItem.setSkuName(cartInfo.getSkuName());
            orderItem.setSkuNum(cartInfo.getSkuNum());
            orderItem.setSkuPrice(cartInfo.getCartPrice());
            orderItem.setThumbImg(cartInfo.getImgUrl());
            orderItemList.add(orderItem);
        }
        //获取订单支付总金额
        BigDecimal totalAmount = new BigDecimal(0);
        for(OrderItem orderItem : orderItemList){
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }

        TradeVo tradeVo = new TradeVo();
        tradeVo.setOrderItemList(orderItemList);
        tradeVo.setTotalAmount(totalAmount);

        return tradeVo;
    }

    /**
     * 提交订单
     * @param orderInfoDto
     * @return
     */
    @Override
    public Long submitOrder(OrderInfoDto orderInfoDto) {
        //1 orderInfoDto 获取所有订单项数据
        List<OrderItem> orderItemList = orderInfoDto.getOrderItemList();

        //2 list<OrderItem> 判空
        if(CollectionUtils.isEmpty(orderItemList)){
            throw new GlobalException(ResultCodeEnum.DATA_ERROR);
        }

        //3 校验商品库存 遍历list集合 得到每个orderItem 校验库存量
        //远程调用获取商品sku信息
        for(OrderItem orderItem : orderItemList){
            //根据skuId获取商品sku信息
            ProductSku productSku = productFeignClient.getBySkuId(orderItem.getSkuId());
            if(productSku == null){
                throw new GlobalException(ResultCodeEnum.DATA_ERROR);
            }
            //检验库存(skuNum:购买数量,stockNum:库存量)
            Integer skuNum = orderItem.getSkuNum();
            Integer stockNum = productSku.getStockNum();
            if(skuNum > stockNum){
                throw new GlobalException(ResultCodeEnum.STOCK_LESS);
            }

        }



        //4 添加数据到orderInfo表(远程调用）
        OrderInfo orderInfo = new OrderInfo();
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        //订单编号(当前时间戳)
        orderInfo.setOrderNo(String.valueOf(System.currentTimeMillis()));
        //用户id
        orderInfo.setUserId(userInfo.getId());
        //用户昵称
        orderInfo.setNickName(userInfo.getNickName());

        //远程调用获取用户地址信息
        UserAddress userAddress = userFeignClient.getUserAddress(orderInfoDto.getUserAddressId());
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverTagName(userAddress.getTagName());
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());
        orderInfo.setReceiverCity(userAddress.getCityCode());
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());
        orderInfo.setReceiverAddress(userAddress.getFullAddress());
        //订单金额
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        orderInfo.setTotalAmount(totalAmount);
        orderInfo.setCouponAmount(new BigDecimal(0));
        orderInfo.setOriginalTotalAmount(totalAmount);
        orderInfo.setFeightFee(orderInfoDto.getFeightFee());
        orderInfo.setPayType(2);
        orderInfo.setOrderStatus(0);

        //封装收获地址信息
        Long userAddressId = orderInfoDto.getUserAddressId();

        orderInfoMapper.save(orderInfo);

        //5 添加数据到orderItem表
        for(OrderItem orderItem : orderItemList){
            //设置订单id
            orderItem.setOrderId(orderInfo.getId());
            orderItemMapper.save(orderItem);
        }

        //6 添加数据到orderLog表
        //记录日志
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderInfo.getId());
        orderLog.setProcessStatus(0);
        orderLog.setNote("提交订单");
        orderLogMapper.save(orderLog);


        //7  把生成的订单从购物车中删掉 远程调用
        cartFeignClient.deleteChecked();

        //8 返回订单id
        return orderInfo.getId();
    }

    /**
     * 订单详细信息
     * @param orderId
     * @return
     */
    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.getById(orderId);
    }

    /**
     * 立即购买
     * @param skuId
     * @return
     */
    @Override
    public TradeVo buy(Long skuId) {
        //封装订单项集合 因为请求格式要求是集合
        ProductSku productSku = productFeignClient.getBySkuId(skuId);
        OrderItem orderItem = new OrderItem();
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(productSku.getSkuName());
        orderItem.setSkuNum(1);
        orderItem.setSkuPrice(productSku.getSalePrice());
        orderItem.setThumbImg(productSku.getThumbImg());
        List<OrderItem> orderItemList = new ArrayList<>();
        orderItemList.add(orderItem);

        TradeVo tradeVo = new TradeVo();
        tradeVo.setOrderItemList(orderItemList);
        //set总金额虽然是一个但也要用高精度
        BigDecimal totalAmount = productSku.getSalePrice();
        tradeVo.setTotalAmount(totalAmount);

        return tradeVo;
    }

    /**
     * 订单查询
     * @param page
     * @param limit
     * @param orderStatus
     * @return
     */
    @Override
    public PageInfo<OrderInfo> findOrderByPage(Integer page, Integer limit, Integer orderStatus) {
        PageHelper.startPage(page, limit);
        Long userId = AuthContextUtil.getUserInfo().getId();
        //根据用户id和订单状态查询订单信息
        List<OrderInfo> orderInfoList = orderInfoMapper.findUserPage(userId, orderStatus);

        //订单项数据
        for (OrderInfo orderInfo : orderInfoList) {
            List<OrderItem> orderItemList = orderItemMapper.findOrderItemList(orderInfo.getId());
            orderInfo.setOrderItemList(orderItemList);
        }
        return  new PageInfo<>(orderInfoList);
    }

    /**
     * 远程调用
     * @param orderNo
     * @return
     */
    @Override
    public OrderInfo getByOrderNo(String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.getByOrderNo(orderNo);
        List<OrderItem> orderItem = orderItemMapper.findOrderItemList(orderInfo.getId());
        orderInfo.setOrderItemList(orderItem);
        return orderInfo;
    }

    //todo 取消订单
}
